package grpc

import (
	"context"
	"encoding/json"
	"fmt"
	"proto/dto"
	"shadow/bll"
	log "shadow/collector/logger"
)

type Shadow struct {
}

func NewShadowRpc() *Shadow {
	return &Shadow{}
}

// DoUpdateAttribute 更新属性
func (s *Shadow) DoUpdateAttribute(ctx context.Context, in *dto.DoUpdateRequest, out *dto.DoUpdateResponse) error {
	switch in.Type {
	case dto.EnUpdateType_STATUS:
		err := bll.InterfaceAgent.UpdateShadowStatus(in.DeviceName, in.Items)
		if err != nil {
			return err
		}
		return nil
	case dto.EnUpdateType_ATTRIBUTE:
		err := bll.InterfaceAgent.UpdateShadowAttributes(in.DeviceName, in.Items)
		if err != nil {
			return err
		}
	}
	*out = dto.DoUpdateResponse{
		Code: 0,
		Msg:  "ok",
	}

	return nil
}

// GetShadow 获取设备影子
func (s *Shadow) GetShadow(ctx context.Context, in *dto.GetShadowRequest, out *dto.GetShadowResponse) error {
	if in.DeviceName == "" {
		return fmt.Errorf("deviceName is empty")
	}

	*out = dto.GetShadowResponse{
		DeviceName: in.DeviceName,
	}

	// TODO: 从数据库中获取设备影子
	value, err := bll.InterfaceAgent.GetShadow(in.DeviceName)
	if err != nil {
		return nil
	}

	data, _ := json.Marshal(value)
	out.Shadow = string(data)
	return nil
}

// GetShadowAttributes 获取设备影子
func (s *Shadow) GetShadowAttributes(ctx context.Context, in *dto.GetShadowAttributesRequest, out *dto.GetShadowAttributesResponse) error {
	if in.DeviceName == "" {
		return fmt.Errorf("deviceName is empty")
	}

	*out = dto.GetShadowAttributesResponse{
		DeviceName: in.DeviceName,
	}

	// TODO: 从数据库中获取设备影子
	value, err := bll.InterfaceAgent.GetShadowAttributes(in.DeviceName)
	if err != nil {
		return nil
	}

	data, _ := json.Marshal(value)
	out.Attribute = string(data)
	return nil
}

// GetShadowStatus 获取设备影子
func (s *Shadow) GetShadowStatus(ctx context.Context, in *dto.GetShadowStatusRequest, out *dto.GetShadowStatusResponse) error {
	if in.DeviceName == "" {
		return fmt.Errorf("deviceName is empty")
	}

	*out = dto.GetShadowStatusResponse{
		DeviceName: in.DeviceName,
	}

	// TODO: 从数据库中获取设备状态
	value, err := bll.InterfaceAgent.GetShadowStatus(in.DeviceName)
	if err != nil {
		return nil
	}

	data, _ := json.Marshal(value)
	out.Status = string(data)
	return nil
}

// GetShadowAttributeKeys 获取设备影子
func (s *Shadow) GetShadowAttributeKeys(ctx context.Context, in *dto.GetShadowAttributeKeysRequest, out *dto.GetShadowAttributeKeysResponse) error {
	if in.DeviceName == "" {
		return fmt.Errorf("deviceName is empty")
	}

	*out = dto.GetShadowAttributeKeysResponse{
		DeviceName: in.DeviceName,
	}

	value, err := bll.InterfaceAgent.GetShadowAttributeValue(in.DeviceName, in.Key)
	if err != nil {
		log.Errorf("GetShadowAttributeKeys error: %v", err)
		return nil
	}

	out.Value = value.(string)

	return nil
}

// GetShadowStatusKeys 获取设备影子
func (s *Shadow) GetShadowStatusKeys(ctx context.Context, in *dto.GetShadowStatusKeysRequest, out *dto.GetShadowStatusKeysResponse) error {
	if in.DeviceName == "" {
		return fmt.Errorf("deviceName is empty")
	}

	*out = dto.GetShadowStatusKeysResponse{
		DeviceName: in.DeviceName,
	}

	value, err := bll.InterfaceAgent.GetShadowStatusValue(in.DeviceName, in.Key)
	if err != nil {
		log.Errorf("GetShadowStatusKeys error: %v", err)
		return nil
	}

	out.Value = value.(string)

	return nil
}
